package xyz.yq56.easytool.utils.reflect;

import java.lang.reflect.Method;

import javax.annotation.Nullable;

import xyz.yq56.easytool.utils.nvll.NullUtil;
import xyz.yq56.easytool.utils.string.TextUtils;

/**
 * 反射工具类
 *
 * @author yi qiang
 * @date 2021/10/1 11:03
 */
public class ReflectUtil {

    private ReflectUtil() {
    }

    /**
     * field名称为小写驼峰时的get方法,符合java命名规范的话一般都能拿到
     *
     * @param clazz 对应的clazz类
     * @param field 属性名称
     * @return 对应的get方法
     */
    @Nullable
    public static Method fieldGetMethod(Class<?> clazz, String field) {
        return getMethod(clazz, fieldGetName(field));
    }

    /**
     * 捕获getMethod方法异常，找不到时返回null即可
     *
     * @param clazz 对应的clazz类
     * @return 对应的get方法
     */
    @Nullable
    public static Method getMethod(Class<?> clazz, String name) {
        try {
            return clazz.getMethod(name);
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    /**
     * 获取属性对应的get方法名称
     *
     * @param field 属性名
     * @return 获取属性get方法名
     */
    public static String fieldGetName(String field) {
        return "get" + TextUtils.upperCamel(field);
    }

    /**
     * 受检异常很难看,这里索性封装一下
     *
     * @param method 待执行的反射方法
     * @param obj    执行方法的对象
     * @param args   方法参数
     * @param <R>    返回值类型
     * @return 返回值
     */
    @SuppressWarnings("unchecked")
    @Nullable
    public static <R> R invokeMethod(Method method, Object obj, Object... args) {
        try {
            if (NullUtil.isOrNull(method, obj)) {
                return null;
            }
            return args == null ? (R) method.invoke(obj) : (R) method.invoke(obj, args);
        } catch (Exception e) {
            return null;
        }
    }

}
